<template>
  <div class="drawer-container">
    <div class="left-container">
      <el-button @click="addRect">+矩形</el-button>
      <el-button @click="addCircle">+原型</el-button>
    </div>
    <div class="right-container">
      <div class="toolbar">
        <el-button v-for="button in buttons" :key="button.text" @click="transform(button.command)" :type="button.type">
          {{ button.text }}
        </el-button>
      </div>
      <div id="container"></div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { Graph, Color } from "@antv/x6";
import { onMounted } from "vue";
import { Snapline } from "@antv/x6-plugin-snapline";
let graph: Graph;

const buttons = [
  { type: "", text: "保存", command: "save" },
  { type: "primary", text: "放大", command: "zoomIn" },
  { type: "success", text: "缩小", command: "zoomOut" },
  { type: "info", text: "复原", command: "zoomTo" },
  { type: "warning", text: "自适应", command: "zoomToFit" },
  { type: "danger", text: "居中", command: "centerContent" },
  { type: "primary", text: "设置大小", command: "prop" },
  { type: "primary", text: "设置样式", command: "attr" }
] as const;

const data = {
  nodes: [
    {
      id: "node1",
      shape: "rect",
      x: 40,
      y: 40,
      width: 100,
      height: 40,
      label: "hello",
      attrs: {
        // body 是选择器名称，选中的是 rect 元素
        body: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
          fill: "#fff",
          rx: 6,
          ry: 6
        }
      }
    },
    {
      id: "node2",
      shape: "rect",
      x: 160,
      y: 180,
      width: 100,
      height: 40,
      label: "world",
      attrs: {
        body: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
          fill: "#fff",
          rx: 6,
          ry: 6
        }
      }
    }
  ],
  edges: [
    {
      shape: "edge",
      source: "node1",
      target: "node2",
      label: "x6",
      attrs: {
        // line 是选择器名称，选中的边的 path 元素
        line: {
          stroke: "#8f8f8f",
          strokeWidth: 1
        }
      }
    }
  ]
};

onMounted(() => {
  const container = document.getElementById("container");
  if (container) {
    graph = new Graph({
      container,
      width: 800,
      height: 600,
      autoResize: true,
      panning: true,
      mousewheel: {
        enabled: true,
        modifiers: "Ctrl",
        maxScale: 4,
        minScale: 0.2
      },
      background: {
        color: "#F2F7FA"
      },
      grid: {
        visible: true,
        type: "doubleMesh",
        args: [
          {
            color: "#eee", // 主网格线颜色
            thickness: 1 // 主网格线宽度
          },
          {
            color: "#ddd", // 次网格线颜色
            thickness: 1, // 次网格线宽度
            factor: 4 // 主次网格线间隔
          }
        ]
      }
    });

    graph.use(
      new Snapline({
        enabled: true
      })
    );

    graph.fromJSON(data);
    graph.centerContent();
  } else {
    console.error("找不到 ID 为 'container' 的元素");
  }
});

const addRect = () => {
  graph.addNode({
    shape: "rect",
    x: 160,
    y: 180,
    width: 100,
    height: 40,
    label: "rect",
    attrs: {
      body: {
        stroke: "#8f8f8f",
        strokeWidth: 1,
        fill: "#fff",
        rx: 6
      }
    }
  });
};

const addCircle = () => {
  graph.addNode({
    shape: "circle",
    x: 160,
    y: 180,
    width: 40,
    height: 40,
    label: "circle",
    attrs: {
      body: {
        stroke: "#8f8f8f",
        strokeWidth: 1,
        fill: "#fff"
      }
    }
  });
};

const transform = (command: string) => {
  const nodes = graph.getNodes();
  switch (command) {
    case "translate":
      graph.translate(20, 20);
      break;
    case "zoomIn":
      graph.zoom(0.2);
      break;
    case "zoomOut":
      graph.zoom(-0.2);
      break;
    case "zoomTo":
      graph.zoomTo(1);
      break;
    case "zoomToFit":
      graph.zoomToFit();
      break;
    case "centerContent":
      graph.centerContent();
      break;
    case "save":
      onSave();
    case "prop":
      nodes.forEach(node => {
        const width = 100 + Math.floor(Math.random() * 50);
        const height = 40 + Math.floor(Math.random() * 10);
        node.prop("size", { width, height });
      });
      break;
    case "attr":
      nodes.forEach(node => {
        const color = Color.random().toHex();
        node.attr("body/fill", color);
      });
      break;
    default:
      break;
  }
};

const onSave = () => {
  const json = graph.toJSON();
  console.log(json);
};
</script>
<style lang="scss" scoped>
.drawer-container {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  .left-container {
    display: flex;
    flex: 0 0 240px;
    flex-direction: row;
    padding: 10px;
    background-color: var(--el-color-white);
    border: 1px solid #eaeaea;
  }
  .right-container {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    background-color: #ffffff;
    .toolbar {
      display: flex;
      flex: 0 0 60px;
      flex-direction: row;
      align-items: center;
      height: 60px;
      padding-left: 10px;
      border-bottom: 1px solid #eaeaea;
    }
    #container {
      flex: 1 1 auto;
      width: 100%;
      height: 100%;
    }
  }
}
</style>
